package com.snakeway.pdfviewer.annotation;

import android.graphics.RectF;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
import com.snakeway.pdfviewer.annotation.base.BaseAnnotation;
import com.snakeway.pdfviewer.annotation.pen.PenBuilder;
import com.snakeway.pdfviewer.annotation.pen.PenType;

import java.util.ArrayList;
import java.util.List;

/**
 * @author snakeway
 */
public class AnnotationBean {
    public static final int TYPE_NORMAL = 0;
    public static final int TYPE_IMAGE = 1;

    @SerializedName("penType")
    public PenType penType;
    @SerializedName("data")
    public String data;
    @SerializedName("page")
    public int page;
    @SerializedName("id")
    public String id;
    @SerializedName("type")
    public int type;

    public AnnotationBean(PenType penType, String data, int page, String id, int type) {
        this.penType = penType;
        this.data = data;
        this.page = page;
        this.id = id;
        this.type = type;
    }

    public AnnotationBean(BaseAnnotation baseAnnotation, boolean needOptimization) {
        penType = baseAnnotation.pen.getPenType();
        Gson gson = new Gson();
        JsonObject jsonObject = gson.toJsonTree(baseAnnotation).getAsJsonObject();
        String penString = jsonObject.get("pen").toString();
        jsonObject.remove("pen");
        jsonObject.addProperty("pen", penString);
        id = jsonObject.get("id").getAsString();
        page = jsonObject.get("page") != null ? jsonObject.get("page").getAsInt() : 0;
        if (baseAnnotation instanceof MarkAnnotation) {
            //app端是通过startIndex和endIndex恢复的,所以data数据是不需要保存的,但是需要转化成其他格式给网页端等显示
            MarkAnnotation markAnnotation = (MarkAnnotation) baseAnnotation;
            List<RectF> datas = mergeMarkData(markAnnotation.data);
            jsonObject.addProperty("mergeData", gson.toJson(datas));
        }
        if (needOptimization) {
            if (baseAnnotation instanceof NotesAnnotation || baseAnnotation instanceof PenAnnotation || baseAnnotation instanceof TextAnnotation) {
                //可移除一些不必要参数,因除data外其他数据如id等的占用较小,暂不处理
            } else if (baseAnnotation instanceof MarkAnnotation) {
                jsonObject.remove("data");
            }
        }
        data = jsonObject.toString();
        type = TYPE_NORMAL;
    }

    /**
     * pdf直角坐标系下mark行数据合并
     */
    private List<RectF> mergeMarkData(List<RectF> rects) {
        RectF indexLine = null;
        List<RectF> lineRects = new ArrayList<>();
        if (rects == null || rects.size() == 0) {
            return lineRects;
        }
        for (int i = 0; i < rects.size(); i++) {
            RectF rectF = rects.get(i);
            if(rectF.left==rectF.right){//pdf可能是word转的,如果是空格换行符是特殊字符就忽略
                continue;
            }
            if (indexLine == null) {
                indexLine = new RectF(rectF.left, rectF.top, rectF.right, rectF.bottom);
                lineRects.add(indexLine);
                continue;
            }
            if (indexLine.bottom > rectF.top) {//判断矩形是否属于同一行,如果新的区域顶部低于旧的底部说明需要换行
                indexLine = new RectF(rectF.left, rectF.top, rectF.right, rectF.bottom);
                lineRects.add(indexLine);
            } else {
                indexLine.left = Math.min(indexLine.left, rectF.left);
                indexLine.top = Math.max(indexLine.top, rectF.top);
                indexLine.right = Math.max(indexLine.right, rectF.right);
                indexLine.bottom = Math.min(indexLine.bottom, rectF.bottom);
            }
        }
        return lineRects;
    }

    public BaseAnnotation getAnnotation() throws Exception {
        if (type == TYPE_IMAGE) {
            return null;
        }
        Gson gson = new Gson();
        JsonObject jsonObject = gson.fromJson(data, JsonObject.class);
        String penString = jsonObject.get("pen").getAsString();
        jsonObject.remove("pen");
        BaseAnnotation annotation = null;
        switch (penType) {
            case COLORPEN:
            case BRUSHPEN:
                annotation = gson.fromJson(jsonObject, PenAnnotation.class);
                break;
            case HIGHLIGHTPEN:
            case DELETELINE:
            case UNDERLINE:
            case UNDERWAVELINE:
                MarkAnnotation markAnnotation = gson.fromJson(jsonObject, MarkAnnotation.class);
                markAnnotation.needInit = true;
                annotation = markAnnotation;
                break;
            case TEXTPEN:
                annotation = gson.fromJson(jsonObject, TextAnnotation.class);
                break;
            case NOTESPEN:
                annotation = gson.fromJson(jsonObject, NotesAnnotation.class);
                break;
            default:
                throw new RuntimeException("error pen type");
        }
        annotation.pen = PenBuilder.getPen(penType, penString, gson);
        return annotation;
    }
}
